package com.wyh.controller.g3controller;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.protobuf.ServiceException;
import com.wyh.common.result.Result;
import com.wyh.domain.dto.g3dto.G3BillingItemsDto;
import com.wyh.domain.dto.gfive.LoginUser;
import com.wyh.domain.enums.g3enums.BillTypeEnum;
import com.wyh.domain.enums.g3enums.SpecialNameEnum;
import com.wyh.domain.enums.g3enums.ThreeMeterTypeEnum;
import com.wyh.domain.po.g3po.*;
import com.wyh.domain.vo.g3vo.BasicBillingInfoVo;
import com.wyh.mapper.g3mapper.*;
import com.wyh.security.gfive.utils.SecurityUtils;
import com.wyh.service.g3service.BillingItemsService;
import com.wyh.service.g3service.FeeclassificationService;
import com.wyh.service.g3service.UnitPriceService;
import com.wyh.utils.g3utils.BillingItemsUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.sql.Timestamp;
import java.util.List;
import java.util.Optional;

import static com.wyh.common.enums.ResultCodeEnum.PARAM_LOST_ERROR;
import static com.wyh.utils.g3utils.BillingItemsUtils.StringToList;

@RestController
@Api(tags = "费项管理")
@RequestMapping("/billingitems")
public class BillingItemsController {

    @Autowired
    BillingItemsService billingItemsService;

    @Autowired
    G3BillingItemsMapper g3BillingItemsMapper;

    @Autowired
    UnitPriceMapper unitPriceMapper;

    @Autowired
    DepositTypeMapper depositTypeMapper;


    @Autowired
    BillingAssociationTableMapper tableMapper;//计费关联表

    @Autowired
    StatisticalTypeMapper statisticalTypeMapper;

    @Autowired
    FormulaMapper formulaMapper;


    @Autowired
    FeeclassificationService feeclassificationService;

    @Autowired
    G3ChargingMapper g3ChargingMapper;


    @Autowired
    UnitPriceService unitPriceService;

    //查询所有计费项目                查询计费项目表，单价表，公式表，费项分类表（费项分类名称），user表（名字），保证金类型表（保证金类型），统计类型表（统计类型名称）
    @ApiOperation("分页查询数据")
    @PostMapping("/findAllBypage")
    public Result<List<G3BillingItemsDto>> findAllByPage(@ApiParam(value = "费项分类id") @RequestParam Optional<Integer> id,//费项分类id
                                                         @ApiParam(value = "费项名称")
                                                         @RequestParam Optional<String> name,//费项名称
                                                         @RequestBody G3Page g3Page) {

        // 检查是否存在 id 参数，如果不存在则返回 null，否则返回 id 的值
        Integer idValue = id.orElse(0);
        // 检查是否存在 name 参数，如果不存在则返回 null，否则返回 name 的值
        String nameValue = name.orElse(null);


        if (g3Page == null) {
            return Result.error(PARAM_LOST_ERROR);
        } else {
            List<G3BillingItemsDto> byPage = g3BillingItemsMapper.findByPage((g3Page.getCurrentPage() - 1) * g3Page.getPageSize(), g3Page.getPageSize(), idValue, nameValue);


            Integer integer = g3BillingItemsMapper.countTotal(idValue, nameValue);
            if (byPage.size() == 0&&integer==null) {
                return Result.error("", "没有数据");
            } else {
                for (G3BillingItemsDto g3BillingItemsDto : byPage) {
                    g3BillingItemsDto.setTotal(integer);
                    if (g3BillingItemsDto.getSpecialName() != null) {

                        g3BillingItemsDto.setSpecialname(SpecialNameEnum.getByCode(g3BillingItemsDto.getSpecialName()));//减冲专项名
                    }
                    if (g3BillingItemsDto.getThreemetertypeid() != null) {
                        g3BillingItemsDto.setThreemetertype(ThreeMeterTypeEnum.getByCode(g3BillingItemsDto.getThreemetertypeid()));//三表类型
                    }
                    if (g3BillingItemsDto.getType() != null) {
                        g3BillingItemsDto.setTypeName(BillTypeEnum.getByCode(g3BillingItemsDto.getType()));//计费性质名
                    }


                }

                return Result.success(byPage);
            }

        }
    }

    @ApiOperation("得到公式")
    @GetMapping("getformula")
    public Result<List<G3Formula>> findFormulas(@ApiParam(value = "公式") @RequestParam(value = "formula") String formula){
        if (formula!=null){
            List<G3Formula> formulas = billingItemsService.getFormulas(formula);
            if (formulas.isEmpty()){
                return Result.error();
            }
            return Result.success(formulas);
        }else {
            return Result.error();
        }

    }

    @ApiOperation("得到单价")
    @GetMapping("getunitprice")
    public Result<List<UnitPrice>> findUnitPrice(@ApiParam(value = "费项id") @RequestParam(value = "billid") Integer billid){

        if (billid!=null){
            QueryWrapper<UnitPrice> unitPriceQueryWrapper = new QueryWrapper<>();
            unitPriceQueryWrapper.eq("billid",billid);
            List<UnitPrice> list = unitPriceService.list(unitPriceQueryWrapper);
            if (list.isEmpty()){
                return Result.error();
            }
            return Result.success(list);
        }else {
            return Result.error();
        }

    }


    //修改状态   费项id，userid
    @ApiOperation("修改状态")
    @GetMapping("/updatestate")
    public Result updateState(@ApiParam(value = "费项id", required = true) @RequestParam(value = "id", required = false) Integer id,
                              HttpServletRequest request) throws ServiceException {

        if (request != null) {
            LoginUser loginUser = SecurityUtils.getLoginUser();
            Integer userid = loginUser.getUser().getId();

            if (id != null && userid != null) {
                //先查询合同费项表中是否有费项id与本id相同,有就不修改

                if (tableMapper.findList(id).size() == 0) {
                    //查询费项id对应费项信息，修改部分信息
                    BillingItems billingItems = g3BillingItemsMapper.selectById(id);
                    if (billingItems == null) {
                        return Result.error("", "没有该数据");
                    }

                    if (billingItems.getState() == 1) {
                        billingItems.setState(0);
                    } else {
                        billingItems.setState(1);
                    }
                    billingItems.setUserid(userid);//修改state和userid

                    //修改时间
                    Timestamp timestamp = new Timestamp(System.currentTimeMillis());
                    billingItems.setUpdatetime(timestamp);

                    int b = g3BillingItemsMapper.updateById(billingItems);
                    if (b!=0) {
                        return Result.success();
                    } else {
                        return Result.error("", "状态修改失败");
                    }
                } else {
                    return Result.error("", "当前费项正在使用，无法停用");
                }
            } else {
                return Result.error(PARAM_LOST_ERROR);
            }

        } else {
            return Result.error(PARAM_LOST_ERROR);
        }

    }


    //获取费项id和被删除的单价id
    @ApiOperation("删除单价")
    @GetMapping("/deleteprice")
    public Result deteleprice(@ApiParam(value = "费项id", required = true) @RequestParam(value = "id", required = false) Integer id,
                              @ApiParam(value = "单价id", required = true) @RequestParam(value = "unid", required = false) Integer unid) {
        if (id != null && unid != null) {


            //先查询计费关联表中有没有使用该费项
            List<BillingAssociationTable> list = tableMapper.findList(id);
            if (list.isEmpty()) {
                int i = unitPriceMapper.deleteById(unid);
                if (i > 0) {
                    return Result.success();
                }
                return Result.error();
            } else {
                for (BillingAssociationTable billingAssociationTable : list) {

//                使用该费项的情况下，得到其中的单价，查询被删除的单价的价格与计费关联表中点击进行比对
                    if (BillingItemsUtils.findNumberIndex(StringToList(billingAssociationTable.getUnitprice()), unid) != -1) {
                        return Result.error("", "当前单价正在使用，无法删除");
                    } else {
                        int i = unitPriceMapper.deleteById(unid);
                        if (i > 0) {
                            return Result.success();
                        } else {
                            return Result.error("", "删除单价失败");
                        }
                    }
                }
                return Result.success();
            }
        } else {
            return Result.error(PARAM_LOST_ERROR);
        }
    }

    //删除公式是指费项表中奖formula属性中的对应id删除
    @ApiOperation("删除计费公式")
    @GetMapping("/deleteformula")//费项id和公式id
    public Result deleteFormula(@ApiParam(value = "费项id", required = true) @RequestParam(value = "id", required = false) Integer id,
                                @ApiParam(value = "公式id", required = true) @RequestParam(value = "fid", required = false) Integer fid) {
        if (id != null && fid != null) {

            //查询费项是否正在被使用
            List<BillingAssociationTable> list = tableMapper.findList(id);
            BillingItems billingItems1 = g3BillingItemsMapper.selectById(id);
            if (billingItems1 == null) {
                return Result.error();
            }
            if (!list.isEmpty()) {
                for (BillingAssociationTable table : list) {
                    //在循环中得到合同费项公式id
                    //-1说明没有使用，不同进行修改
                    int numberIndex = BillingItemsUtils.findNumberIndex(StringToList(table.getFormula()), fid);
                    if (numberIndex == -1) {
                        boolean b = billingItemsService.updateFormula(billingItems1, fid);
                        if (b) {
                            return Result.success();
                        } else {
                            return Result.error();
                        }
                    } else {
                        return Result.error("", "当前公式正在使用，无法停用");
                    }
                }
            } else {//没有被使用的费项，
                String removeAndJoinNumbers = BillingItemsUtils.findRemoveAndJoinNumbers(StringToList(billingItems1.getFormula()), fid);
                if (!removeAndJoinNumbers.equals(billingItems1.getFormula())) {//判断修改后的字符串与原字符串是否相等，相等说明需要删除的公式没有被使用
                    billingItems1.setFormula(removeAndJoinNumbers);
                    int i = g3BillingItemsMapper.updateById(billingItems1);

                    if (i > 0) {
                        return Result.success();
                    } else {
                        return Result.error();
                    }
                } else {
                    return Result.error("", "未使用该公式");
                }
            }
            return Result.success();
        } else {
            return Result.error(PARAM_LOST_ERROR);
        }
    }


    //用于新增费项时展示的数据
    @ApiOperation("新增基础数据")
    @PostMapping("/basicbillinfo")
    public Result<BasicBillingInfoVo> findAllInfo() {
        BasicBillingInfoVo basicInfo = new BasicBillingInfoVo();
        basicInfo.setBillType(BillTypeEnum.getAllBillingTypes());//计费性质
        basicInfo.setSpecialName(SpecialNameEnum.getAllSpecialName());//预存
        basicInfo.setThreeMeterType(ThreeMeterTypeEnum.getAllThreeMeterType());//三表
        basicInfo.setDepositTypes(depositTypeMapper.selectList(null));//保证金类型
        basicInfo.setStatisticalTypes(statisticalTypeMapper.selectList(null));//统计类型
        basicInfo.setTreestructure(feeclassificationService.getTreeStructure());//费项分类树
        basicInfo.setG3Formulas(formulaMapper.selectList(null));//所有计算公式
        return Result.success(basicInfo);
    }


    //新增费项
    @Transactional
    @ApiOperation("新增费项")
    @PostMapping("/add")
    public Result addBillingItem(@RequestBody G3BillingItemsDto g3BillingItemsDto,
                                 HttpServletRequest request) throws ServiceException {
        if (request != null) {

            LoginUser loginUser = SecurityUtils.getLoginUser();
            Integer userid = loginUser.getUser().getId();
            if (userid == null) {
                return Result.error();
            }

            //得到组织id
            int organizationId = g3BillingItemsMapper.getOrganizationId(userid);
            //最上级组织id
            int parentOrganization = billingItemsService.getParentOrganization(organizationId);

            int count = g3BillingItemsMapper.findByname(g3BillingItemsDto.getName(), parentOrganization);

            if (count>0){
                return Result.error("500","费项名称重复");
            }

            if (g3BillingItemsDto != null && !g3BillingItemsDto.getUnitPrices().isEmpty()) {
                g3BillingItemsDto.setUserid(userid);
                g3BillingItemsDto.setParentid(parentOrganization);
                BillingItems billingItems = BillingItemsUtils.getBillingItems(g3BillingItemsDto);

                if (g3BillingItemsDto.getG3Formulas()==null||g3BillingItemsDto.getG3Formulas().size()>10){
                    return Result.error();
                }else {
                    StringBuilder idsStringBuilder = new StringBuilder();
                    for (G3Formula g3Formula : g3BillingItemsDto.getG3Formulas()) {
                        Integer id = g3Formula.getId();
                        if (idsStringBuilder.length() > 0) {
                            idsStringBuilder.append(","); // 在非首个元素前添加逗号
                        }
                        idsStringBuilder.append(id);
                    }

                    String idsString = idsStringBuilder.toString();
                    billingItems.setFormula(idsString);
                }

                //得到公式
                //判断公式和单价数量
                if (g3BillingItemsDto.getUnitPrices() == null||g3BillingItemsDto.getUnitPrices().size() > 20) {
                        return Result.error();
                }
                // 自增后的id
                int insert = g3BillingItemsMapper.insert(billingItems);

                int newId = billingItems.getId();
                List<UnitPrice> unitPrices = g3BillingItemsDto.getUnitPrices();
                if (!unitPrices.isEmpty()) {
                    //修改操作人，时间，费项id
                    for (UnitPrice unitPrice : unitPrices) {
                        unitPrice.setUpdatetime(new Timestamp(System.currentTimeMillis()));
                        unitPrice.setUserid(billingItems.getUserid());
                        unitPrice.setBillid(newId);
                    }
                    boolean b = unitPriceService.saveBatch(unitPrices);
                    if (insert != 0 && b) {
                        return Result.success("插入成功");
                    } else {
                        return Result.error("插入失败");
                    }
                } else {
                    return Result.error(PARAM_LOST_ERROR);
                }
            } else {
                return Result.error(PARAM_LOST_ERROR);
            }
        } else {
            return Result.error(PARAM_LOST_ERROR);
        }

    }


    //编辑 修改费项和单价表
    @ApiOperation("修改费项")
    @PostMapping("/update")
    @Transactional
    public Result update(@RequestBody G3BillingItemsDto g3BillingItemsDto,
                         HttpServletRequest request) throws ServiceException {
        if (request != null) {
            LoginUser loginUser = SecurityUtils.getLoginUser();
            Integer userid = loginUser.getUser().getId();
            if (userid == null) {
                return Result.error();
            }
            BillingItems billingItems = g3BillingItemsMapper.selectById(g3BillingItemsDto.getId());

            int count = g3BillingItemsMapper.findByname(g3BillingItemsDto.getName(), billingItems.getParentid());
            if (count>0){
                return Result.error("500","费项名称重复");
            }

            if (g3BillingItemsDto != null && g3BillingItemsDto.getId() != null) {

                g3BillingItemsDto.setUserid(userid);
                if (g3BillingItemsDto.getFormula() != null && BillingItemsUtils.StringToList(g3BillingItemsDto.getFormula()).size() > 10) {
                    return Result.error();
                }
                if (g3BillingItemsDto.getUnitPrices() != null && g3BillingItemsDto.getUnitPrices().size() > 20) {
                    return Result.error();
                }


                //修改费项
                boolean b = billingItemsService.updateBillingItem(g3BillingItemsDto);

                //修改合同费项表中名称  通过费项id修改名称
                boolean c = billingItemsService.updateName(g3BillingItemsDto.getId(), g3BillingItemsDto.getName());


                //修改多个单价
                boolean u = billingItemsService.updateUnitPrices(g3BillingItemsDto);

                if (u && c && b) {
                    return Result.success();
                } else {

                    return Result.error();
                }
            } else {
                return Result.error(PARAM_LOST_ERROR);
            }
        } else {
            return Result.error(PARAM_LOST_ERROR);
        }

    }


}














